<template>
  <div class="h-[calc(100vh-46px)] flex flex-col">
    <div class="relative">
      <Carousel
        v-model:selectedId="humanId"
        :carouselList="noFailHumanInfoList.infoList"
        :userAssetDetailData="userAssetDetailData"
      />
      <div class="side-upload-img-box" @click="handleUploadImgTip">
        <svg-icon name="icon-shangchuan" :size="16" color="#fff" />
        <div class="mt-5">添</div>
        <div>加</div>
        <div>照</div>
        <div>片</div>
      </div>
    </div>
    <div class="flex justify-between items-center px-15">
      <div class="flex-1 flex">
        <div
          class="flex items-center pl-2 pr-10 h-30 rounded-15 bg-1D1D1F"
          @click="handleSelectTimbre"
        >
          <div class="h-26 w-26 relative rounded-[50%] overflow-hidden">
            <van-image
              class="relative"
              :src="TIMBRE_SEX_IMG_MAP[noFailTimbreInfo.timbreGender || 3]"
              :fit="'cover'"
            />
            <div
              class="h-12 w-12 absolute bottom-0 right-0 rounded-[50%] bg-black flex items-center justify-center"
            >
              <svg-icon name="icon-bofangyuyin" :size="8" color="#fff" />
            </div>
          </div>
          <div class="pl-5 pr-10 text-white text-12">
            <span v-if="noFailTimbreInfo.timbreAnchorName">{{
              noFailTimbreInfo.timbreAnchorName
            }}</span>
            <span v-if="noFailTimbreInfo.timbreName">{{
              noFailTimbreInfo.timbreName.split("/")[1]
            }}</span>
          </div>
        </div>
      </div>
      <div>
        <NormalTabs
          class="text-15"
          :tabs="categoryInfoList"
          :active-id="categoryInfoId"
          :tab-class="tabClass"
          @update:active-id="categoryInfoId = $event"
        />
      </div>
    </div>
    <div
      class="mt-15 mx-15 rounded-10 bg-1D1D1F min-h-124 text-666666 text-14 flex flex-col flex-grow-1"
    >
      <div
        v-if="Number(categoryInfoId) === 1"
        class="flex flex-col p-12 h-full"
      >
        <div
          class="h-full break-all overflow-y-auto"
          :class="{ 'text-white': themeDescription }"
          @click="handleTextareaCopy"
        >
          <div v-if="aiTextId" class="flex items-center rounded-15">
            <div class="loading-circle w-14 h-14 rounded-[50%]" />
            <div class="ml-10 text-14 leading-30">文案生成中...</div>
          </div>
          <div v-else>
            {{ themeDescription || "想要照片说什么内容？请写在这里" }}
          </div>
        </div>
        <div class="flex justify-center items-center pt-10 mt-auto text-white">
          <div
            class="flex justify-center items-center px-8 leading-24 h-24 rounded-5 bg-2F2F33"
            @click="copyReplaceTips('randomCopy')"
          >
            <svg-icon name="icon-suiji" :size="12" color="#fff" />
            <div class="ml-5 text-11">随机</div>
          </div>
          <div
            class="flex justify-center items-center px-8 leading-24 h-24 rounded-5 bg-2F2F33 ml-10"
            @click="copyReplaceTips('copyWriting')"
          >
            <svg-icon name="icon-deepseek" :size="12" color="#fff" />
            <div class="ml-5 text-11">· AI文案</div>
          </div>
          <div
            class="flex justify-center items-center px-8 leading-24 h-24 rounded-5 bg-2F2F33 ml-10"
            @click="themeDescription = ''"
          >
            <svg-icon
              name="icon-shanchu"
              :size="12"
              :color="themeDescription ? '#fff' : '#666'"
            />
            <div
              class="ml-5 text-11"
              :class="{
                'text-white': themeDescription,
                'text-666666': !themeDescription
              }"
            >
              清空
            </div>
          </div>
          <div class="ml-auto text-14 text-666666">
            {{ themeDescription.length }}/5000
          </div>
        </div>
      </div>
      <div
        v-if="Number(categoryInfoId) === 2"
        class="flex flex-col h-full justify-around"
      >
        <div
          class="mx-auto h-48 w-275 rounded-10 bg-313138 text-white text-14 flex justify-center items-center"
        >
          <svg-icon name="icon-a-jingyin_dianji3x" :size="16" color="#fff" />
          <div class="pl-5 font-bold">录制音频</div>
        </div>
        <div
          class="mx-auto h-48 w-275 rounded-10 bg-313138 text-white text-14 flex justify-center items-center"
        >
          <svg-icon name="icon-weixin1" :size="16" color="#fff" />
          <div class="pl-5 font-bold">微信上传</div>
        </div>
        <div class="text-999999 text-12 mx-auto">请上传5秒-20分钟内的音频</div>
      </div>
    </div>
    <div
      class="my-20 px-20"
      :class="{ 'opacity-50': themeDescription.length < 6 }"
    >
      <ButtonFooter button-text="立刻生成" @confirm="confirmGenerate" />
    </div>
    <!-- 上传图片提示  -->
    <UploadImgTips v-model:visible="uploadImgTipVisible" />
    <!-- 警告提示  -->
    <WarningTips
      v-model:visible="warningTipsVisible"
      :title="warningTipsTitle"
      :content="warningTipsContent"
      :show-cancel-button="warningTipsShowCancelButton"
      :confirm-text="warningTipsConfirmText"
      @confirm="confirmWarningTips"
      @cancel="cancelWarningTips"
    />
    <!-- 编写AI文案  -->
    <van-popup
      v-model:show="textareaCopyVisible"
      round
      position="bottom"
      :style="{ height: '100%' }"
      @opened="handlePopupOpened"
    >
      <div class="flex flex-col size-full">
        <nav-bar :NavBarType="2" @confirm="textareaCopyVisible = false" />
        <div class="mt-20 h-0 px-15 flex-grow-1 flex flex-col myField">
          <div v-if="aiTextId" class="flex items-center rounded-15">
            <div class="loading-circle w-14 h-14 rounded-[50%]" />
            <div class="ml-10 text-14 leading-30">文案生成中...</div>
          </div>
          <van-field
            v-else
            ref="textareaFieldRef"
            v-model="textareaCopyContent"
            rows="30"
            autosize
            type="textarea"
            maxlength="5000"
            class="flex-grow-1 h-0 text-white w-full text-15"
            placeholder="想要数字人说什么内容？请写在这里"
          />
        </div>
        <div class="p-15 mt-auto w-full text-white">
          <div class="flex justify-center items-center mt-auto text-white">
            <div
              class="flex justify-center items-center px-8 leading-24 h-24 rounded-5 bg-2F2F33"
              @click="copyReplaceTips('randomCopy')"
            >
              <svg-icon name="icon-suiji" :size="12" color="#fff" />
              <div class="ml-5 text-11">随机</div>
            </div>
            <div
              class="flex justify-center items-center px-8 leading-24 h-24 rounded-5 bg-2F2F33 ml-10"
              @click="copyReplaceTips('copyWriting')"
            >
              <svg-icon name="icon-deepseek" :size="12" color="#fff" />
              <div class="ml-5 text-11">· AI文案</div>
            </div>
            <div
              class="flex justify-center items-center px-8 leading-24 h-24 rounded-5 bg-2F2F33 ml-10"
              @click="textareaCopyContent = ''"
            >
              <svg-icon
                name="icon-shanchu"
                :size="12"
                :color="textareaCopyContent ? '#fff' : '#666'"
              />
              <div
                class="ml-5 text-11"
                :class="{
                  'text-white': textareaCopyContent,
                  'text-666666': !textareaCopyContent
                }"
              >
                清空
              </div>
            </div>
            <div class="ml-auto text-14 text-666666">
              {{ textareaCopyContent.length }}/5000
            </div>
          </div>
          <div class="mt-10">
            <ButtonFooter button-text="完成" @confirm="confirmFinish" />
          </div>
        </div>
      </div>
    </van-popup>
    <!--  选择音色弹出框  -->
    <SelectTimbrePopup
      v-if="selectTimbreVisible"
      v-model:visible="selectTimbreVisible"
      :my-no-fail-timbre-list="noFailTimbreInfoList.infoList"
      :user-asset-detail="userAssetDetailData"
      :select-no-fail-timbre-category-id="noFailTimbreCategoryId"
      :select-no-fail-timbre-info="noFailTimbreInfo"
      @confirm="confirmSelectTimbre"
    />
    <!--  创建视频提示  -->
    <CreateVideoTips
      v-if="createVideoTipsVisible"
      v-model:visible="createVideoTipsVisible"
      :video-id="createHumanVideoId"
    />
  </div>
</template>

<script setup lang="ts">
import {
  onMounted,
  ref,
  nextTick,
  onActivated,
  onBeforeUnmount,
  computed
} from "vue";
import {
  AiCoinInfoData,
  getAiCoin,
  getNoFailHumanInfoList,
  getNoFailTimbreInfoList,
  InfoListData,
  NoFailHumanInfoListData,
  NoFailTimbreInfoData,
  NoFailTimbreInfoListData
} from "@/api/CreatePictureVideo";
import { getUserAssetDetail, UserAssetDetailData } from "@/api/MyHuman";
import NormalTabs from "@/components/NormalTabs/index.vue";
import {
  AI_COPY_STATUS_ENUM,
  INPUT_TYPE_TAB,
  TIMBRE_SEX_IMG_MAP
} from "@/constants";
import {
  AiTitleExampleVoInfoData,
  createHumanVideo,
  getAiTitleExampleVoList
} from "@/api/AiCopyGenerator";
import NavBar from "@/components/NavBar/index.vue";
import router from "@/router";
import { useRoute } from "vue-router";
import { getAiText } from "@/api/AiCopyGenHistory";
import { showToast } from "vant";
import { templateInfo } from "@/api/TempleVideo";
import { getLocalStorage, removeLocalStorage, setLocalStorage } from "@/utils";
defineOptions({
  name: "CreatePictureVideo"
});
const route = useRoute();

// 创建视频弹出框
const createVideoTipsVisible = ref(false);
// 立即生成
const confirmGenerate = () => {
  if (themeDescription.value.length < 6) {
    showToast("文本内容太短，请调整文案内容");
    return;
  }
  getAiCoinPort();
};
// 所需AI币
const aiCoinParam = ref<AiCoinInfoData>();
// 获取所需AI币
const getAiCoinPort = async () => {
  const param = {
    aiCoinRatioType: 1,
    audioLen: "",
    content: themeDescription.value,
    contentType: 1
  };
  aiCoinParam.value = await getAiCoin(param);
  warningTipsType.value = "createVideo";
  warningTipsVisible.value = true;
  warningTipsTitle.value = "提示";
  warningTipsContent.value = `本次预计消耗${aiCoinParam.value.aiCoinAmount}个AI币（失败将自动返回）`;
  warningTipsConfirmText.value = "立即生成";
  warningTipsShowCancelButton.value = false;
};
// 选择音色弹出框
const selectTimbreVisible = ref(false);
// 音色选择
const handleSelectTimbre = () => {
  selectTimbreVisible.value = true;
};
// 文案详情
const textareaCopyContent = ref("");
// van-field的引用
const textareaFieldRef = ref<any>(null);
// 编写ai文案
const textareaCopyVisible = ref(false);
// 编写ai文案弹窗
const handleTextareaCopy = () => {
  textareaCopyContent.value = themeDescription.value;
  textareaCopyVisible.value = true;
};
// 完成操作
const confirmFinish = () => {
  themeDescription.value = textareaCopyContent.value;
  textareaCopyVisible.value = false;
};
// 上传图片弹窗
const uploadImgTipVisible = ref(false);
// 上传图片操作
const handleUploadImgTip = () => {
  uploadImgTipVisible.value = true;
};

// 样式配置
const tabClass = ref({
  activeColor: "text-white",
  textColor: "text-999999",
  textSize: "text-15",
  activeTextSize: "text-16"
});
// 分类请求列表
const categoryInfoList = INPUT_TYPE_TAB;
const categoryInfoId = ref<string>("1");
// 切换数字人
const changeHumanId = (index: number) => {
  humanId.value = noFailHumanInfoList.value.infoList[index].humanId;
};
// 模板ID
const templateId = ref("");
// 当前数字人id
const humanId = ref("");
// 数字人列表
const noFailHumanInfoList = ref<NoFailHumanInfoListData>({
  infoList: [],
  noticeCount: 0
});
// 获取数字人列表
const getNoFailHumanInfoListPort = async () => {
  if (route.params.id) {
    templateId.value = route.params.id as string;
    await templateInfoPort();
  }
  const result = await getNoFailHumanInfoList();

  // 判断 noFailHumanInfoList.value.infoList 是否有值，如果有的话 result.infoList要加上它
  if (noFailHumanInfoList.value.infoList.length > 0) {
    result.infoList = [
      ...noFailHumanInfoList.value.infoList,
      ...result.infoList
    ];
  }
  noFailHumanInfoList.value = result;
  humanId.value = noFailHumanInfoList.value.infoList[0].humanId;
  noFailHumanInfoList.value.infoList.unshift({
    humanId: "0",
    humanImageUrl: "",
    humanImgHigh: 0,
    humanImgWidth: 0,
    humanTaskFailMessage: "",
    humanTaskStatus: ""
  });
};
// 扩展NoFailTimbreInfoData接口以包含commonCategoryId字段
interface ExtendedNoFailTimbreInfoData extends NoFailTimbreInfoData {
  commonCategoryId: string;
}
// 获取模板信息
const templateInfoPort = async () => {
  const templateRequestParam = {
    id: templateId.value
  };
  const result = await templateInfo(templateRequestParam);
  noFailHumanInfoList.value.infoList.unshift(result);
  noFailTimbreId.value = result.timbreInfoVo.timbreId;
  // 使用类型断言为扩展接口
  noFailTimbreCategoryId.value = (
    result.timbreInfoVo as ExtendedNoFailTimbreInfoData
  ).commonCategoryId;
  noFailTimbreInfo.value = result.timbreInfoVo;
};
// 音色id
const noFailTimbreId = ref("");
// 已选择音色分类
const noFailTimbreCategoryId = ref("0");
// 已选择音色
const noFailTimbreInfo = ref<NoFailTimbreInfoData>({
  timbreAnchorName: "",
  timbreName: "",
  isCollect: 0,
  timbreGender: 3,
  timbreId: "",
  timbreTaskFailMessage: "",
  timbreTaskStatus: "",
  timbreVersionType: 0
});
// 音色列表
const noFailTimbreInfoList = ref<NoFailTimbreInfoListData>({
  infoList: [],
  noticeCount: 0
});
// 获取音色列表
const getNoFailTimbreInfoListPort = async () => {
  noFailTimbreInfoList.value = await getNoFailTimbreInfoList();
  if (noFailTimbreInfoList.value.infoList.length && !templateId.value) {
    noFailTimbreId.value = noFailTimbreInfoList.value.infoList[0].timbreId;
    noFailTimbreInfo.value = noFailTimbreInfoList.value.infoList[0];
  }
};
// 获取音色详情
const confirmSelectTimbre = (
  timbreInfo: NoFailTimbreInfoData,
  timbreCategoryId: string
) => {
  noFailTimbreInfo.value = timbreInfo;
  noFailTimbreCategoryId.value = timbreCategoryId;
};

// 分类请求列表
const userAssetDetailData = ref<UserAssetDetailData>({
  aiCoinAmount: 0,
  aiCoinBalance: 0,
  exTimbreAmount: 0,
  exTimbreBalance: 0,
  humanAmount: 0,
  humanBalance: 0,
  humanNormalAmount: 0,
  humanNormalBalance: 0,
  humanNormalCustomAmount: 0,
  humanNormalCustomBalance: 0,
  noTrainFreeVideoAmount: 0,
  noTrainFreeVideoBalance: 0,
  noTrainVideoAmount: 0,
  noTrainVideoBalance: 0,
  timbreAmount: 0,
  timbreBalance: 0,
  totalHumanAmount: 0,
  totalHumanBalance: 0,
  videoMakeBalance: 0
});
// 分类请求接口
const getUserAssetDetailPort = async () => {
  userAssetDetailData.value = await getUserAssetDetail();
};
// 添加ai范文列表
const themeDescription = ref("");
// 警告弹窗
const warningTipsVisible = ref(false);
// 警告类型
const warningTipsType = ref("randomCopy");
// 警告标题
const warningTipsTitle = ref("");
// 警告文案
const warningTipsContent = ref("");
// 警告确认按钮文字
const warningTipsConfirmText = ref("确定");
// 警告是否显示取消按钮
const warningTipsShowCancelButton = ref(true);
// 是否警告过
const warningTipsNum = ref(0);
// 文案替换提示
const copyReplaceTips = (type: string) => {
  warningTipsType.value = type;
  let contentStr = "";
  if (textareaCopyVisible.value) {
    contentStr = textareaCopyContent.value;
  } else {
    contentStr = themeDescription.value;
  }
  const isThemeFromExample = aiTitleExampleVoList.value.some(
    item => item.title === contentStr
  );
  if (
    contentStr &&
    warningTipsNum.value === 0 &&
    ((warningTipsType.value === "randomCopy" &&
      (aiTitleExampleVoList.value.length === 0 || !isThemeFromExample)) ||
      warningTipsType.value === "copyWriting")
  ) {
    warningTipsNum.value = 1;
    warningTipsVisible.value = true;
    warningTipsTitle.value = "将会替换现有内容";
    warningTipsContent.value =
      "使用此功能会生成新的文案内容，现有的文字将会被替换";
    warningTipsConfirmText.value = "确定";
    warningTipsShowCancelButton.value = true;
    return;
  }
  if (warningTipsType.value === "randomCopy") {
    handleAiTitleExampleVoList();
  } else if (warningTipsType.value === "copyWriting") {
    navigateTo("AiCopyGenerator");
  }
};
// 确定警告弹出框
const confirmWarningTips = () => {
  if (warningTipsType.value === "randomCopy") {
    handleAiTitleExampleVoList();
  } else if (warningTipsType.value === "copyWriting") {
    if (templateId.value) {
      setLocalStorage("CreatePictureVideo_TemplateId", templateId.value);
    }
    navigateTo("AiCopyGenerator");
  } else if (warningTipsType.value === "createVideo") {
    createHumanVideoPort();
  }
};
// 创建数字人视频id
const createHumanVideoId = ref("");
// 创建数字人视频
const createHumanVideoPort = async () => {
  const param = {
    aiCoin: aiCoinParam.value.aiCoinAmount,
    aiCoinBalance: userAssetDetailData.value.aiCoinBalance,
    contentText: themeDescription.value,
    contentType: 1,
    humanId: humanId.value,
    humanType: 1,
    timbreId: noFailTimbreInfo.value.timbreId,
    timbreKey: noFailTimbreInfo.value.timbreId,
    timbreType: Number(noFailTimbreCategoryId.value) === 0 ? 2 : 1,
    videoSpeed: 1
  };
  createHumanVideoId.value = await createHumanVideo(param);
  createVideoTipsVisible.value = true;
  await getUserAssetDetailPort();
};
// 取消警告弹出框
const cancelWarningTips = () => {
  warningTipsNum.value = 0;
};
// 随机获取文案
const aiTitleExampleVoList = ref<AiTitleExampleVoInfoData[]>([]);
const aiTitleExampleVoNum = ref(0);
const handleAiTitleExampleVoList = async () => {
  if (
    aiTitleExampleVoNum.value == 0 &&
    aiTitleExampleVoList.value.length === 0
  ) {
    aiTitleExampleVoList.value = await getAiTitleExampleVoList({
      categoryId: 0
    });
  }
  const aiTitleExampleVoStr =
    aiTitleExampleVoList.value[aiTitleExampleVoNum.value].title;
  aiTitleExampleVoNum.value++;

  if (textareaCopyVisible.value) {
    textareaCopyContent.value = aiTitleExampleVoStr;
  } else {
    themeDescription.value = aiTitleExampleVoStr;
  }
  if (aiTitleExampleVoNum.value == aiTitleExampleVoList.value.length) {
    aiTitleExampleVoNum.value = 0;
  }
};

// 处理弹窗打开后的事件
const handlePopupOpened = () => {
  // 在下一个tick中聚焦到输入框
  nextTick(() => {
    if (textareaFieldRef.value && textareaFieldRef.value.focus) {
      textareaFieldRef.value.focus();
    }
  });
};
// 跳转页面
const navigateTo = (routeName: string) => {
  router.push({
    name: routeName,
    params: { routeName: "CreatePictureVideo" }
  });
};
// 获取ai文案
const aiTextId = ref("");
// 轮询定时器存储对象
const pollingTimers = ref<Record<string, number>>({});
// 组件卸载标志
let isUnmounted = false;
// 启动轮询
const startPolling = (itemId: string) => {
  // 如果已经在轮询，则不再重复启动
  if (pollingTimers.value[itemId]) return;

  const poll = async () => {
    if (isUnmounted) return;

    try {
      const detail = await getAiText(itemId);
      if (isUnmounted) return;
      // 如果状态变为完成，清除定时器
      if (detail.status === AI_COPY_STATUS_ENUM.DONE) {
        aiTextId.value = "";
        if (textareaCopyVisible.value) {
          textareaCopyContent.value = detail.content;
          handlePopupOpened();
        } else {
          themeDescription.value = detail.content;
        }
        removeLocalStorage("AiCopyGenHistory_AiTextId");
        clearPollingTimer(itemId);
      } else {
        // 继续轮询
        pollingTimers.value[itemId] = window.setTimeout(poll, 1500);
      }
    } catch (error) {
      if (isUnmounted) return;
      console.error("轮询出错:", error);
      // 出错后继续轮询
      pollingTimers.value[itemId] = window.setTimeout(poll, 3000);
    }
  };
  // 立即开始轮询
  poll();
};
// 清除单个轮询定时器
const clearPollingTimer = (itemId: string) => {
  if (pollingTimers.value[itemId]) {
    clearTimeout(pollingTimers.value[itemId]);
    delete pollingTimers.value[itemId];
  }
};
// 清除所有轮询定时器
const clearAllPollingTimers = () => {
  Object.keys(pollingTimers.value).forEach(itemId => {
    clearTimeout(pollingTimers.value[itemId]);
  });
  pollingTimers.value = {};
};
onActivated(() => {
  aiTextId.value = getLocalStorage("AiCopyGenHistory_AiTextId");
  if (aiTextId.value) {
    startPolling(aiTextId.value);
  }
});

onMounted(() => {
  getNoFailHumanInfoListPort();
  getNoFailTimbreInfoListPort();
  getUserAssetDetailPort();
});

onBeforeUnmount(() => {
  isUnmounted = true;
  // 清除所有轮询定时器
  clearAllPollingTimers();
});
</script>

<style scoped>
.side-upload-img-box {
  z-index: 100;
  position: absolute;
  left: 0;
  top: 104px;
  width: 30px;
  height: 115px;
  background-image: linear-gradient(167deg, #6c3dff 0%, #0f07ff 100%);
  border-radius: 0 10px 10px 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: #fff;
  font-size: 13px;
  transition: all 1s;
  line-height: 16px;
}
</style>
